package com.wg.net.session;

import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.wg.net.SendResult;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;

/**
 * WebSocket会话实现类（继承自TcpSession，扩展WebSocket协议支持）
 * <p>
 * 职责：
 * - 封装WebSocket帧的编解码逻辑
 * - 重写消息发送方法以适配WebSocket协议
 *
 * @author 少爷123
 */
public class WebSocketSession extends TcpSession {
    private static final Log log = LogFactory.get();

    /**
     * 构造WebSocket会话（绑定Netty Channel）
     *
     * @param channel Netty Channel对象（不可为null）
     */
    public WebSocketSession(Channel channel) {
        super(channel);
    }

    @Override
    public SendResult send(byte[] data) {
        if (!channel.isActive()) {
            log.warn("WebSocket消息发送失败：Channel未激活 | Channel={}", channel);
            return SendResult.Disconnected;
        }
        if (!channel.isWritable()) {
            log.warn("WebSocket消息发送失败：Channel不可写（缓冲区已满） | Channel={}", channel);
            return SendResult.SendBufferFull;
        }

        try {
            writeAndFlush(data);
            return SendResult.Ok;
        } catch (Exception e) {
            log.error("WebSocket消息发送异常 | Channel={}", channel, e);
            return SendResult.Failed;
        }
    }

    @Override
    protected void writeAndFlush(byte[] data) {
        WebSocketFrame frame = buildFrame(data);
        channel.writeAndFlush(frame, channel.voidPromise());
    }

    /**
     * 构建WebSocket二进制帧（长度头+数据体）
     *
     * @param data 待发送的字节数据
     * @return WebSocket二进制帧
     */
    private BinaryWebSocketFrame buildFrame(byte[] data) {
        ByteBuf buf = Unpooled.buffer(4 + data.length); // 预分配4字节长度头+数据体
        buf.writeInt(data.length); // 写入长度头（大端序）
        buf.writeBytes(data); // 写入数据体
        return new BinaryWebSocketFrame(buf);
    }
}